﻿namespace JUpload.Net
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Web;

    /// <summary>
    /// The class manages the retrieval of the uploaded files from the request and inserts in the cache.
    /// </summary>
    public class FileUtility
    {
        /// <summary>
        /// Manages the retrieval of the uploaded files from the request and inserts in the cache.
        /// </summary>
        /// <param name="context">The given httpcontext</param>
        public static void ProcessRequest(HttpContext context)
        {
            var Request = context.Request;
            var Response = context.Response;
            var Server = context.Server;
        
            var reqBytes = Request.BinaryRead(Request.TotalBytes);

            if (Request.Files.Count > 0)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder(reqBytes.Length + 1);
                sb.Length = reqBytes.Length + 1;

                for (int i = 0; i < reqBytes.Length; i++)
                {
                    sb[i] = (char)reqBytes[i];
                }

                string sReq = sb.ToString();

                string boundary = Request.ContentType.Replace("multipart/form-data; boundary=", "");
                string[] parts = sReq.Split(new string[] { boundary }, 110, StringSplitOptions.None);

                int globalStartIndex = 0;

                foreach (string part in parts)
                {
                    if (part.Length > "Content-Disposition: form-data; name=\"".Length)
                    {
                        int start = part.IndexOf("name=\"") + "name=\"".Length;
                        int end = part.IndexOf("\"", start + 1);

                        string name = part.Substring(start, end - start);

                        start = part.IndexOf("filename=\"") + "filename=\"".Length;
                        end = part.IndexOf("\"", start + 1);

                        string filename = part.Substring(start, end - start);

                        bool found = false;

                        foreach (string s in Request.Files)
                        {
                            if (name == s)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            start = part.IndexOf("\r\n\r\n", end + 2) + 4;
                            //start = part.IndexOf("\r\n\r\n", oldStart + 1) + 2;

                            //if (start == 1) start = oldStart;

                            end = part.Length - 3;

                            System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
                            System.Text.Decoder utf8Decode = encoder.GetDecoder();

                            byte[] fileContent = new byte[end - start];
                            for (int index = start; index < start + fileContent.Length; index++)
                            {
                                fileContent[index - start] = reqBytes[index + globalStartIndex];
                            }

                            MemoryStream fileMs = new MemoryStream();
                            BinaryWriter sw = new BinaryWriter(fileMs);
                            sw.Write(fileContent);

                            int filesCount = (int)context.Cache["JUploadFilesCount"];
                            if (filesCount == 0)
                            {
                                List<UploadedFile> uplFiles = new List<UploadedFile>();
                                context.Cache.Insert("JUploadUploadedFiles", uplFiles);
                            }

                            filesCount++;

                            context.Cache.Remove("JUploadFilesCount");
                            context.Cache.Insert("JUploadFilesCount", filesCount);

                            List<UploadedFile> uploadedFiles = (List<UploadedFile>)context.Cache["JUploadUploadedFiles"];

                            uploadedFiles.Add(new UploadedFile() { FileName = filename, FileStream = new MemoryStream(fileMs.GetBuffer()) });

                            sw.Close();
                        }
                    }

                    globalStartIndex += part.Length + boundary.Length;
                }

                Response.Write("SUCCESS");
                Response.Flush();
                Response.End();
            }
        }

        //private MultipartContentElement[] GetMultipartContent()
        //{
        //    if (this._multipartContentElements == null)
        //    {
        //        byte[] multipartBoundary = this.GetMultipartBoundary();
        //        if (multipartBoundary == null)
        //        {
        //            return new MultipartContentElement[0];
        //        }
        //        HttpRawUploadedContent entireRawContent = this.GetEntireRawContent();
        //        if (entireRawContent == null)
        //        {
        //            return new MultipartContentElement[0];
        //        }
        //        this._multipartContentElements = HttpMultipartContentTemplateParser.Parse(entireRawContent, entireRawContent.Length, multipartBoundary, this.ContentEncoding);
        //    }
        //    return this._multipartContentElements;
        //}

    }
}
